import java.util.Random;

public class Numerics {
	public Debugger debug;
	private boolean show;

	public Numerics(Debugger dbg) {
		debug = dbg;
		show = false;
	}

	public Signal s1(int A, short t1, int d, double f) {
		int count = (int) (d * f);
		double[] s = new double[count];
		for (int i = 0; i < count; i++) {
			s[i] = f1(A);
			if (show == true)
				debug.msg("Probka :[" + (i + 1) + "][" + s[i] + "]");
		}
		Signal sig = new Signal(t1, f, count, s);
		if (show == true)
			debug.msg("Zwrocilem sygnal s1 z parametrami:\n\tt1:" + t1
					+ "[s]\n\tczestotliwosc: " + f + "[Hz]\n\tilosc probek: "
					+ count + "\n\tczas trwania d: " + d);
		return sig;
	}

	private double f1(int A) {
		Random rand = new Random();
		double val = (rand.nextFloat() * 2 * A) - A;
		return val;
	}

	public Signal s2(int A, short t1, int d, double f) {
		int count = (int) (d * f);
		double[] s = new double[count];
		for (int i = 0; i < count; i++) {
			s[i] = f2();
			if (show == true)
				debug.msg("Probka :[" + (i + 1) + "][" + s[i] + "]");
		}
		double max = findMaxG(count, s);
		for (int i = 0; i < count; i++) {
			s[i] /= max;
			s[i] *= A;
		}
		Signal sig = new Signal(t1, f, count, s);
		if (show == true)
			debug.msg("Zwrocilem sygnal s2 z parametrami:\n\tt1:" + t1
					+ "[s]\n\tczestotliwosc: " + f + "[Hz]\n\tilosc probek: "
					+ count + "\n\tczas trwania d: " + d);
		return sig;
	}

	public double findMaxG(int count, double[] sign) {
		double max = 0;
		for (int i = 0; i < count; i++) {
			if (Math.abs(sign[i]) > max)
				max = sign[i];
		}
		return max;
	}

	private float f2() {
		Random rand = new Random();
		float val = (float) rand.nextGaussian();
		return val;
	}

	public Signal s3(int A, short t0, double d, double e, double f) {
		int count = (int) (d * f);
		double[] s = new double[count];
		for (int i = 0; i < count; i++) {
			double ctime = i / f;
			s[i] = f3(A, ctime, e, t0);
			if (show == true)
				debug.msg("Probka :[" + (i + 1) + ":" + ctime + "][" + s[i]
						+ "]");
		}
		debug.msg(">>"+f);
		Signal sig = new Signal(t0, f, count, s);
		debug.msg("Zwrocilem sygnal s3 z parametrami:\n\tt1:" + t0
				+ "[s]\n\tczestotliwosc: " + f + "[Hz]\n\tokres T: " + e
				+ "\n\tilosc probek: " + count + "\n\tczas trwania d: " + d);
		return sig;
	}

	private double f3(int A, double t, double T, int t0) {
		double val = A * Math.sin(((2 * Math.PI) / T) * (t - t0));
		return val;
	}

	public Signal s4(int A, short t0, int d, int T, double f) {
		int count = (int) (d * f);
		double[] s = new double[count];
		for (int i = 0; i < count; i++) {
			double ctime = i / f;
			s[i] = f4(A, ctime, T, t0);
			if (show == true)
				debug.msg("Probka :[" + (i + 1) + "][" + s[i] + "]");
		}
		Signal sig = new Signal(t0, f, count, s);
		if (show == true)
			debug.msg("Zwrocilem sygnal s4 z parametrami:\n\tt1:" + t0
					+ "[s]\n\tczestotliwosc: " + f + "[Hz]\n\tokres T: " + T
					+ "\n\tilosc probek: " + count + "\n\tczas trwania d: " + d);
		return sig;
	}

	private double f4(int A, double t, int T, int t0) {
		double val = 1.0
				/ 2.0
				* A
				* (Math.sin(((2 * Math.PI) / T) * (t - t0)) + Math.abs(Math
						.sin(((2 * Math.PI) / T) * (t - t0))));
		return val;
	}

	public Signal s5(int A, short t0, int d, int T, double f) {
		int count = (int) (d * f);
		double[] s = new double[count];
		for (int i = 0; i < count; i++) {
			double ctime = i / f;
			s[i] = f5(A, ctime, T, t0);
			if (show == true)
				debug.msg("Probka :[" + (i + 1) + "][" + s[i] + "]");
		}
		Signal sig = new Signal(t0, f, count, s);
		if (show == true)
			debug.msg("Zwrocilem sygnal s5 z parametrami:\n\tt1:" + t0
					+ "[s]\n\tczestotliwosc: " + f + "[Hz]\n\tokres T: " + T
					+ "\n\tilosc probek: " + count + "\n\tczas trwania d: " + d);
		return sig;
	}

	private double f5(int A, double t, int T, int t0) {
		double val = 1.0 / 2.0 * A
				* (Math.abs(Math.sin(((2 * Math.PI) / T) * (t - t0))));
		return val;
	}

	public Signal s6(int A, short t0, int d, int T, float kw, double f) {
		int count = (int) (d * f);
		int ileK = (int) (d / T);
		double[] s = new double[count];
		for (int i = 0; i < count; i++) {
			double ctime = i / f;
			int k = 0;
			while (k < ileK) {
				if ((ctime >= (double) (k * T) - t0)
						&& (ctime < (double) (kw * T) + (k * T) - t0)) {
					s[i] = (double) A;
					break;
				}
				if ((ctime >= (double) (kw * T) - (k * T) + t0)
						&& (ctime < (double) (T + (k * T) - t0))) {
					s[i] = (double) 0;
					break;
				} else
					k++;
			}
			if (show == true)
				debug.msg("Probka :[" + (i + 1) + "][" + s[i] + "]");
		}
		Signal sig = new Signal(t0, f, count, s);
		if (show == true)
			debug.msg("Zwrocilem sygnal s6 z parametrami:\n\tt1:" + t0
					+ "[s]\n\tczestotliwosc: " + f + "[Hz]\n\tokres T: " + T
					+ "\n\tilosc probek: " + count + "\n\tczas trwania d: " + d);
		return sig;
	}

	public Signal s7(int A, short t0, int d, int T, float kw, double f) {
		int count = (int) (d * f);
		int ileK = (int) (d / T);
		int k = 0;
		double[] s = new double[count];
		for (int i = 0; i < count; i++) {
			double ctime = i / f;
			while (k < ileK) {
				if ((ctime >= (double) (k * T) - t0)
						&& (ctime < (double) (kw * T) + (k * T) - t0)) {
					s[i] = (double) A;
					break;
				}
				if ((ctime >= (double) (kw * T) - (k * T) + t0)
						&& (ctime < (double) (T + (k * T) - t0))) {
					s[i] = (double) -A;
					break;
				} else
					k++;
			}
			if (show == true)
				debug.msg("Probka :[" + (i + 1) + "][" + s[i] + "]");
		}
		Signal sig = new Signal(t0, f, count, s);
		if (show == true)
			debug.msg("Zwrocilem sygnal s7 z parametrami:\n\tt1:" + t0
					+ "[s]\n\tczestotliwosc: " + f + "[Hz]\n\tokres T: " + T
					+ "\n\tilosc probek: " + count + "\n\tczas trwania d: " + d);
		return sig;
	}

	public Signal s8(int A, short t0, int d, int T, float kw, double f) {
		int count = (int) (d * f);
		int ileK = (int) (d / T);
		int k = 0;
		double[] s = new double[count];
		for (int i = 0; i < count; i++) {
			double ctime = i / f;
			while (k < ileK) {
				if ((ctime >= (k * T + t0)) && (ctime < (kw * T + k * T + t0))) {
					s[i] = (double) (A / (kw * T)) * (ctime - k * T - t0);
					break;
				}
				if (ctime >= (kw * T + t0 + k * T)
						&& (ctime < (T + k * T + t0))) {
					s[i] = (double) ((-A) / (T * (1.0 - kw)))
							* (ctime - k * T - t0) + (A / (1.0 - kw));
					break;
				} else
					k++;
			}
			if (show == true)
				debug.msg("Probka :[" + (i + 1) + "][" + s[i] + "]");
		}
		Signal sig = new Signal(t0, f, count, s);
		if (show == true)
			debug.msg("Zwrocilem sygnal s8 z parametrami:\n\tt1:" + t0
					+ "[s]\n\tczestotliwosc: " + f + "[Hz]\n\tokres T: " + T
					+ "\n\tilosc probek: " + count + "\n\tczas trwania d: " + d + "\n\twspol. wyp: "+ kw);
		return sig;
	}

	public Signal s9(int A, short t0, int d, double ts, double f) {
		int count = (int) (d * f);
		double[] s = new double[count];
		for (int i = 0; i < count; i++) {
			double ctime = (double) t0 + (double) i * (1.0 / f);
			s[i] = f9(A, ctime, ts);
			if (show == true)
				debug.msg("Probka :[" + (i + 1) + "][" + s[i] + "]");
		}
		Signal sig = new Signal(t0, f, count, s);
		if (show == true)
			debug.msg("Zwrocilem sygnal s9 z parametrami:\n\tt0:" + t0
					+ "[s]\n\tczestotliwosc: " + f + "[Hz]\n\tczas skoku ts: "
					+ ts + "\n\tilosc probek: " + count
					+ "\n\tczas trwania d: " + d);
		return sig;
	}

	private double f9(int A, double t, double ts) {
		double val = 0;
		if (t > ts)
			val = A;
		if (t == ts)
			val = (1.0 / 2.0) * A;
		if (t < ts)
			val = 0;
		return val;
	}

	public Signal s10(int A, double t0, int d, double ts, double f) {
		int count = (int) (d * f);
		double[] s = new double[count];
		for (int i = 0; i < count; i++) {
			double ctime = (double) t0 + (double) i * (1.0 / f);
			s[i] = f10(A, ctime, ts);
			if (show == true)
				debug.msg("Probka :[" + (i + 1) + "][" + s[i] + "]");
		}
		Signal sig = new Signal((short) t0, f, count, s);
		if (show == true)
			debug.msg("Zwrocilem sygnal s10 z parametrami:\n\tt0:" + t0
					+ "[s]\n\tczestotliwosc: " + f + "[Hz]\n\tczas skoku ts: "
					+ ts + "\n\tilosc probek: " + count
					+ "\n\tczas trwania d: " + d);
		return sig;
	}

	private double f10(int A, double t, double ts) {
		double val = 0;
		if (t == ts)
			val = A;
		return val;
	}

	public Signal s11(int A, double t0, int d, float p, double f) {
		int count = (int) (d * f);
		double[] s = new double[count];
		for (int i = 0; i < count; i++) {
			double ctime = i / f;
			s[i] = f11(A, ctime, p);
			if (show == true)
				debug.msg("Probka :[" + (i + 1) + "][" + s[i] + "]");
		}
		Signal sig = new Signal((short) t0, f, count, s);
		if (show == true)
			debug.msg("Zwrocilem sygnal s11 z parametrami:\n\tt0:" + t0
					+ "[s]\n\tczestotliwosc: " + f
					+ "[Hz]\n\tprawdopodobienstwo p: " + p
					+ "\n\tilosc probek: " + count + "\n\tczas trwania d: " + d);
		return sig;
	}

	private double f11(int A, double t, float p) {
		double val = 0;
		Random rand = new Random();
		float x = rand.nextFloat();
		debug.msg("" + x);
		if (x < p)
			val = A;
		else
			val = 0;
		return val;
	}

}